/*
 * @features: 快速查找指定类型的vm组件
 * @description: 说明
 * @Date: 2021-10-02 14:34:21
 * @Author: judu233(769471424@qq.com)
 * @LastEditTime: 2021-10-10 17:39:00
 * @LastEditors: judu233
 */

import c3d from "../../../cc";
const { ccclass, property, executeInEditMode, disallowMultiple, menu } = c3d._decorator;
/**查找列表 */
enum FIND_LIST { VmBase, VmParent, VmLabel, VmProgress, VmState, }
/**快速操作 */
enum ACTION_MODE { 查找组件, 激活组件, 替换组件, 删除组件 };


@ccclass(`VmFind`)
export default class VmFind {
    @property({ displayName: `快速功能` })
    fastEdit = false;

    @property({ displayName: `查找列表`, type: [c3d.Enum(FIND_LIST)], visible() { return this.fastEdit; } })
    findList: FIND_LIST[] = [];

    @property({ displayName: `操作类型`, type: c3d.Enum(ACTION_MODE), visible() { return this.fastEdit; } })
    actionType: ACTION_MODE = ACTION_MODE.查找组件;

    @property({ displayName: `查找`, tooltip: `勾选后,会自动查找 find list 中填写的组件`, visible() { return this.actionType === ACTION_MODE.查找组件 && this.fastEdit; } })
    get findTrigger() { return false; }
    set findTrigger(v: boolean) { this.setComponents(0); }

    @property({ displayName: `激活`, tooltip: `勾选后,会批量激活 find list 中填写的组件`, visible() { return this.actionType === ACTION_MODE.激活组件 && this.fastEdit; } })
    get enableTrigger() { return false; }
    set enableTrigger(v: boolean) { this.setComponents(1); }

    @property({ displayName: `关闭`, tooltip: `勾选后,会批量关闭 find list 中填写的组件`, visible() { return this.actionType === ACTION_MODE.激活组件 && this.fastEdit; } })
    get disableTrigger() { return false; }
    set disableTrigger(v: boolean) { this.setComponents(2); }

    @property({ displayName: `允许删除`, tooltip: `允许删除节点的组件,确定需要移除请勾选,防止误操作`, visible() { return this.actionType === ACTION_MODE.删除组件 && this.fastEdit; } })
    allowDelete: boolean = false;

    @property({ displayName: `[ X DELETE X ]`, tooltip: `勾选后,会批量删除 find list 中填写的组件`, visible() { return this.allowDelete && this.actionType === ACTION_MODE.删除组件 && this.fastEdit; } })
    get deleteTrigger() { return false; }
    set deleteTrigger(v: boolean) { this.setComponents(3); }

    @property({ displayName: `开头路径`, tooltip: `匹配的路径,匹配规则: 搜索开头为 game的路径`, visible() { return this.actionType === ACTION_MODE.替换组件 && this.fastEdit; } })
    targetPath: string = `game`;

    @property({ displayName: `替换路径`, tooltip: `替换的路径,将匹配到的路径替换`, visible() { return this.actionType === ACTION_MODE.替换组件 && this.fastEdit; } })
    replacePath: string = `*`;

    @property({ displayName: `替换`, tooltip: `勾选后,会批量替换掉指定的路径`, visible() { return this.actionType === ACTION_MODE.替换组件 && this.fastEdit; } })
    get replaceTrigger() { return false; }
    set replaceTrigger(v: boolean) { this.setComponents(4); }

    @property({ displayName: `显示引用`, tooltip: `是否搜集绑定VM组件的节点?`, visible() { return this.actionType === ACTION_MODE.查找组件 && this.fastEdit; } })
    canCollectNodes: boolean = false;

    @property({ displayName: `查找到的引用`, type: [c3d.Node], readonly: true, tooltip: `收集到绑定了VM组件相关的节点，可以自己跳转过去`, visible() { return this.canCollectNodes && this.actionType === ACTION_MODE.查找组件 && this.fastEdit; } })
    collectNodes: c3d.Node[] = [];

    /**设置组件 */
    setComponents(state: number) {
        let title = `搜索到当前节点下面的组件`;
        switch (state) {
            case 0: title = `搜索到当前节点下面的组件`; break;
            case 1: title = `激活以下节点的组件`; break;
            case 2: title = `关闭以下节点的组件`; break;
            case 3: title = `删除以下节点的组件`; break;
            case 4: title = `替换以下节点的路径`; break;
            default: break;
        }
        c3d.log(title)
        c3d.log(`______________________`)
        this.findList.forEach(findEnum => this.searchComponent(FIND_LIST[findEnum], state));
        c3d.log(`______________________`)
    }


    /**
     * 查找组件并设置
     * @param className 
     * @param state 0-查找节点组件 1-激活节点组件 2-关闭节点组件 3-移除节点组件
     */
    searchComponent(className: string, state: number = 0) {
        /**收集节点清空 */
        this.collectNodes = [];

        // let comps = this.node.getComponentsInChildren(className) as VmBase[];
        // if (comps == null || comps.length < 1) return;
        // c3d.log(`[` + className + `]:`);
        // comps.forEach(v => {
        //     let ext = ``;
        //     if (state <= 3) {
        //         //区分模板模式路径
        //         if (v.useMultipathMode && v.watchPathArr) {
        //             ext = `  Path:[${v.watchPathArr.join(` | `)}]`;
        //         } else if (v.watchPath) {
        //             ext = `  Path:[${v.watchPath}]`;
        //         }
        //     }
        //     c3d.log(this.getNodePath(v.node) + ext);

        //     switch (state) {
        //         case 0:
        //             if (this.canCollectNodes && this.collectNodes.indexOf(v.node) === -1) {
        //                 this.collectNodes.push(v.node);
        //             }
        //             break;
        //         case 1: v.enabled = true; break;
        //         case 2: v.enabled = false; break;
        //         case 3: v.destroy(); break;
        //         case 4://替换指定路径
        //             let targetPath = this.targetPath;
        //             let replacePath = this.replacePath;
        //             if (v.useMultipathMode) {
        //                 v.watchPathArr.forEach((path, i) => {
        //                     v.watchPathArr[i] = this._replaceNodePath(path, targetPath, replacePath);
        //                 });
        //             } else {
        //                 v.watchPath = this._replaceNodePath(v.watchPath, targetPath, replacePath);
        //             }
        //         default: break;
        //     }
        // });
    }

    /**替换节点路径 */
    _replaceNodePath(path: string, search: string, replace: string) {
        let pathArr = path.split(`.`);
        let searchArr = search.split(`.`);
        let replaceArr = replace.split(`.`)
        let match = true;
        for (let i = 0; i < searchArr.length; i++) {
            if (pathArr[i] !== searchArr[i]) {
                //未匹配上
                match = false;
                break;
            }
        }
        //匹配成功准备替换路径
        if (match) {
            for (let i = 0; i < replaceArr.length; i++) {
                pathArr[i] = replaceArr[i];
            }
            c3d.log(` 路径更新:`, path, `>>>`, pathArr.join(`.`))
        }
        return pathArr.join(`.`);
    }

    /**查找节点路径 */
    getNodePath(parentNode: c3d.Node) {
        let array = [];
        while (parentNode) {
            let p = parentNode.parent;
            if (p) {
                array.push(parentNode.name);
                parentNode = p;
            } else {
                break;
            }
        }
        return array.reverse().join(`/`);
    }

}


